//
// AWS Manager - A free AWS console application demonstrating advanced concepts
// Copyright (C) 2008-2010 Sean O'Dell. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.awsmanager.common;

import com.sun.webui.jsf.model.Option;
import com.xerox.amazonws.ec2.AvailabilityZone;
import com.xerox.amazonws.ec2.EC2Exception;
import com.xerox.amazonws.ec2.Jec2;
import com.xerox.amazonws.ec2.RegionInfo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.net.URL;
import java.util.Collection;
import java.util.Iterator;

/**
 *
 * @author Sean ODell
 */
public class EC2Connection {

    private Jec2 ec2 = null;
    private String statusmsg = null;
    private ArrayList ec2ZoneNames = new ArrayList();
    private ArrayList ec2RegionNames = new ArrayList();
    private Map ec2ZoneToRegion = new HashMap();
    private Map ec2RegionInfo = new HashMap();

    public EC2Connection() {
    }

    public EC2Connection(Properties awsProps, Map connectToRegions, Map ec2ServerInfo) {
        connect(awsProps, connectToRegions, ec2ServerInfo);
    }

    public Jec2 getec2() {
        return ec2;
    }

    public String getstatusmsg() {
        return statusmsg;
    }

    public Map getEc2RegionInfo() {
        return ec2RegionInfo;
    }

    public ArrayList getEc2RegionNames() {
        return ec2RegionNames;
    }

    public ArrayList getEc2ZoneNames() {
        return ec2ZoneNames;
    }

    public Map getEc2ZoneToRegion() {
        return ec2ZoneToRegion;
    }

    public void connect(Properties awsProps, Map connectToRegions, Map ec2RegionsInfo) {

        List<String> params = new ArrayList<String>();
        List<AvailabilityZone> ec2Zones = null;

        if ( (awsProps.getProperty("aws.accessKey").equals(""))
          || (awsProps.getProperty("aws.secretKey").equals(""))) {
            statusmsg = "Cannot connect to server, keys not supplied correctly.";
            return;
        }

        if (ec2RegionsInfo != null) {

            Collection ec2Regions = ec2RegionsInfo.values();
            Iterator itr = ec2Regions.iterator();
            
            while (itr.hasNext()) {
                EC2Region ec2Region = (EC2Region) itr.next();

                if (connectToRegions.get(ec2Region.getRegionName()) != null) {

                    Jec2 rc = null;
                    if (ec2Region.getServerPort() > 0) {
                        rc = new Jec2(awsProps.getProperty("aws.accessKey"),
                          awsProps.getProperty("aws.secretKey"),
                            false, ec2Region.getServer(), ec2Region.getServerPort());
                    } else {
                        rc = new Jec2(awsProps.getProperty("aws.accessKey"),
                          awsProps.getProperty("aws.secretKey"),
                            false, ec2Region.getServer());
                    }

                    if (ec2Region.getServerResourcePrefix() != null) {
                        rc.setResourcePrefix(ec2Region.getServerResourcePrefix());
                    }

                    if (ec2Region.getProxyHost() != null) {
                        if (ec2Region.getProxyPort() > 0) {
                            rc.setProxyValues(ec2Region.getProxyHost(), ec2Region.getProxyPort());
                        } else {
                            rc.setProxyValues(ec2Region.getProxyHost(), 80);
                        }
                    }

                    ec2Region.setRegionConnection(rc);

                    try {
                        ec2Zones = ec2Region.getRegionConnection().describeAvailabilityZones(params);
                    } catch (EC2Exception ex) {
                        Logger.getLogger(EC2Connection.class.getName()).log(Level.SEVERE, "describeAvailabilityZones", ex);
                    }

                    if (ec2Zones != null) {
                        for (AvailabilityZone ec2Zone : ec2Zones) {
                            this.ec2ZoneToRegion.put(ec2Zone.getName(), ec2Region.getRegionName());
                            ec2ZoneNames.add(ec2Zone.getName());
                        }
                    }

                    ec2RegionInfo.put(ec2Region.getRegionName(), ec2Region);
                    ec2RegionNames.add(ec2Region.getRegionName());
                }
            }
            Collections.sort(ec2ZoneNames);
            Collections.sort(ec2RegionNames);
        }
    }

    public Option[] getZoneOptions() {
        Option[] zoneOptions = new Option[this.ec2ZoneNames.size()];
        for (int i = 0; i < this.ec2ZoneNames.size(); i++) {
            zoneOptions[i] = new Option(ec2ZoneNames.get(i));
        }
        return zoneOptions;
    }

    public Option[] getZoneOptionsFilter() {
        Option[] zoneOptions = new Option[this.ec2ZoneNames.size() + 1];
        zoneOptions[0] = new Option("", "Select Zone");
        for (int i = 0; i < this.ec2ZoneNames.size(); i++) {
            zoneOptions[i + 1] = new Option(ec2ZoneNames.get(i));
        }
        return zoneOptions;
    }

    public Option[] getRegionOptions() {
        Option[] regionOptions = new Option[this.ec2RegionNames.size()];
        for (int i = 0; i < this.ec2RegionNames.size(); i++) {
            regionOptions[i] = new Option(ec2RegionNames.get(i));
        }
        return regionOptions;
    }

    public Option[] getRegionOptionsFilter() {
        Option[] regionOptions = new Option[this.ec2RegionNames.size() + 1];
        regionOptions[0] = new Option("", "Select Region");
        for (int i = 0; i < this.ec2RegionNames.size(); i++) {
            regionOptions[i + 1] = new Option(ec2RegionNames.get(i));
        }
        return regionOptions;
    }
}